package com.wisnews.service.sec.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wisnews.mapper.sec.PermissionMapper;
import com.wisnews.pojo.sec.entity.Operator;
import com.wisnews.pojo.sec.entity.Permission;
import com.wisnews.service.sec.IPermissionService;
import com.wisnews.util.Constants;
import com.wisnews.util.MenuTreeNode;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 系统权限信息 服务实现类
 * </p>
 *
 * @author yuyd
 * @since 2020-12-20
 */
@Service
@Slf4j
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements IPermissionService {

    @Autowired
    private  PermissionMapper permissionMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public MenuTreeNode getMenuInfo() {

        Session session = SecurityUtils.getSubject().getSession();
        Operator operator = (Operator)session.getAttribute(Constants.SYS_CODE.LOGIN_USER);
        List<Permission> permissions = null;
        if (Objects.isNull(operator)){
            return new MenuTreeNode();
        }

        Object o = redisTemplate.opsForValue().get(operator.getOperatorId() + ".menuInfo");
        if (!Objects.equals(o,null) && o instanceof MenuTreeNode){
            log.info("<==读取用户"+operator.getCode()+"-reids菜单信息成功");
            return (MenuTreeNode) o;
        }

        log.info("==>首次访问用户："+operator.getCode()+"-菜单信息存入redis");

        if (!Objects.isNull(operator)){
           permissions = permissionMapper.getPermissionForRole(operator.getOperatorRole());
        }
        MenuTreeNode menuTreeNode = menuBuilder(permissions);

        redisTemplate.opsForValue().set(operator.getOperatorId()+".menuInfo",menuTreeNode);

        return menuTreeNode;
    }

    @Override
    public IPage getPermissionForPage(Permission req, IPage<Permission> toPage) {
        LambdaQueryWrapper<Permission> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(StringUtils.isNotBlank(req.getPid()),Permission::getPid,req.getPid())
                .like(StringUtils.isNotBlank(req.getName()),Permission::getName,req.getName())
                .like(StringUtils.isNotBlank(req.getUrl()),Permission::getUrl,req.getUrl())
                .eq(StringUtils.isNotBlank(req.getState()),Permission::getState,req.getState());
        return permissionMapper.getPermissionForPage(lambdaQueryWrapper,toPage);
    }

    /**
     * @description: //菜单树生成类
     * @param:
     * @return:
     * @author yuyd
     * @date: 2021/2/12 12:04
     */
    private MenuTreeNode menuBuilder(List<Permission> list){
        //根节点
        MenuTreeNode root = new MenuTreeNode();

        if (Objects.isNull(list)){
            return root;
        }
        list.forEach(permission -> {
            //父节点
            if ("0".equals(permission.getPid())){
                MenuTreeNode menuTreeNode = new MenuTreeNode();
                menuTreeNode.setData(permission);
                root.getChildren().add(menuTreeNode);
            }
        });
        list.forEach(permission -> {
            root.getChildren().forEach(
                    permissionMenuTreeNode -> {
                        if (permission.getPid().equals(permissionMenuTreeNode.getData().getPermissionId())){
                            MenuTreeNode menuTreeNode = new MenuTreeNode();
                            menuTreeNode.setData(permission);
                            menuTreeNode.setChildren(null);
                            permissionMenuTreeNode.getChildren().add(menuTreeNode);
                        }
                    }
            );
        } );

        return root;
    }
}
